home *** CD-ROM | disk | FTP | other *** search
-
- /************************************************************
- * Program: RMENU Menu Interpreter
- * Module: rmenu2.c
- * Top-level menu processing
- * Written by: Leor Zolman, 7/91
- ************************************************************/
-
- #include "cmenu.h"
- #include "rcmenu.h"
-
- #if __STDC
- #pragma hdrstop
- #endif
-
- #include <ctype.h>
-
-
- /************************************************************
- * sub_menu():
- * Run a local menu at the given nesting level
- * Default command/menu path is supplied via "path".
- ************************************************************/
-
- int sub_menu(mnum, path)
- int mnum;
- char *path;
- {
- MENU2 *M2p = LMenus[nestlev].Menus[mnum];
- MENU *Mp = &M2p -> Menu;
- char newpath[MAX_PATH];
-
- int cur_item = 0;
- int sel_val = 0;
- int factor;
-
- draw_menu(M2p, cur_item); /* display the menu */
-
- strcpy(newpath, make_path(path, Mp -> path));
-
- while (1)
- {
- switch (get_cmd(Mp -> nitems, cur_item, &sel_val))
- {
- case KEY_UP:
- draw_item(M2p, cur_item, NORMAL, NO);
- cur_item = cur_item ? cur_item - 1 :
- Mp -> nitems - 1;
- draw_item(M2p, cur_item, STANDOUT, YES);
- break;
-
- case KEY_DOWN:
- draw_item(M2p, cur_item, NORMAL, NO);
- cur_item = (cur_item == Mp -> nitems - 1) ? 0 :
- cur_item + 1;
- draw_item(M2p, cur_item, STANDOUT, YES);
- break;
-
- case KEY_RIGHT:
- if (Mp -> columns == 1)
- break;
-
- draw_item(M2p, cur_item, NORMAL, NO);
-
- factor = MAX_IROWS / Mp -> spacing;
- if (cur_item + factor < Mp -> nitems)
- cur_item += factor;
- else
- cur_item %= factor;
-
- draw_item(M2p, cur_item, STANDOUT, YES);
- break;
-
- case KEY_LEFT:
- if (Mp -> columns == 1)
- break;
- draw_item(M2p, cur_item, NORMAL, NO);
-
- factor = MAX_IROWS / Mp -> spacing;
- if (cur_item >= factor)
- cur_item -= factor;
- else
- while (cur_item + factor < Mp -> nitems)
- cur_item += factor;
-
- draw_item(M2p, cur_item, STANDOUT, YES);
- break;
-
- case KEY_SHOW:
- show_item(M2p, cur_item, newpath);
- break;
-
- case KEY_RUN:
- if (M2p -> Items[cur_item] -> acttyp == ACT_EXIT)
- return OK;
- if (do_item(M2p, cur_item, newpath) == EXITALL)
- return EXITALL;
-
- switch(M2p -> Items[cur_item] -> nextcode)
- {
- case NXT_FIRST:
- cur_item = 0;
- break;
-
- case NXT_LAST:
- cur_item = M2p -> Menu.nitems - 1;
- break;
-
- case NXT_NEXT:
- if (cur_item < M2p -> Menu.nitems - 1)
- cur_item++;
- break;
-
- case NXT_DIRECT:
- cur_item = M2p -> Items[cur_item] -> nextitem;
- break;
- }
-
- draw_menu(M2p, cur_item); /* redisplay menu */
- break;
-
- case K_DIRECT:
- if ((sel_val - 1) != cur_item)
- {
- draw_item(M2p, cur_item, NORMAL, NO);
- cur_item = sel_val - 1;
- draw_item(M2p, cur_item, STANDOUT, YES);
- }
- break;
-
- case K_SHELL:
- if (M2p -> Menu.escape == YES ||
- (M2p -> Menu.escape == DEFAULT && DEF_ESCAPE == YES))
- {
- #if SHELL_PROMPT
- if (put_msg(0, SH_PROMPT_STR) == ESC)
- break;
- #else
- move(ERR_ROW, 0);
- hlight_on();
- addstr("Invoking shell. . .");
- hlight_end();
- #endif
-
- pre_shell(); /* set up for shell call */
- system(SysShell); /* run a shell */
- post_shell(); /* restore everything */
-
- draw_menu(M2p, cur_item);
- }
- else
- put_msg(1, "Sorry, shell escapes are disabled.");
- break;
-
- case K_EXIT:
- return OK;
-
- case K_EXITALL:
- return EXITALL;
-
- case K_VERSION:
- put_msg(0, " RMENU Menu Interpreter v%s ",
- VERSION);
- break;
-
- case K_UNKNOWN:
- beep();
- }
- refresh();
- }
- }
-
-
- /************************************************************
- * draw_menu():
- * Display the entire menu, including all prompts,
- * and titles and help text (if any) for current item
- * on the screen.
- ************************************************************/
-
- Void draw_menu(M2p, curr)
- MENU2 *M2p;
- int curr;
- {
- MENU *Mp = &M2p -> Menu;
- int title_len = strlen(Mp -> title);
- int i, j;
-
- clear();
-
- move(TITLE_ROW, (SCREEN_COLS - title_len)/2);
- addstr(Mp -> title); /* Put up menu title */
-
- for (i = 0; i < Mp -> nitems; i++)
- if (i != curr)
- draw_item(M2p, i, NORMAL, NO);
-
- draw_item(M2p, curr, STANDOUT, YES);
-
- move(PROMPT_ROW, 0);
- addstr(MENU_OPTS);
- if (Mp -> escape == YES ||
- (Mp -> escape == DEFAULT && DEF_ESCAPE == YES))
- addstr(MENU_SHELL);
- addstr(MENU_PROMPT);
- getyx(stdscr, echoy, echox); /* save coords of item # echo area */
-
- refresh(); /* display the window */
-
- }
-
-
- /************************************************************
- * draw_item():
- * Display a single item (the current item) of the
- * specified menu, using the specified video mode.
- * Display assiciated help text only if "dohelp"
- * is TRUE.
- ************************************************************/
-
- Void draw_item(M2p, item, vid_mode, dohelp)
- MENU2 *M2p;
- int item, vid_mode, dohelp;
- {
- ITEM *Ip = M2p -> Items[item];
- COORDS *Cp = &M2p -> coords[item];
- int j;
- int help_len;
-
- move (Cp->ypos, Cp->xpos);
- printw("%2d.", item + 1);
-
- if (vid_mode == STANDOUT)
- hlight_on();
-
- printw(" %s", Ip -> text);
-
- for (j = 0; j < Cp -> spaces_needed; j++)
- addch(' ');
-
- if (vid_mode == STANDOUT)
- hlight_end();
-
-
- if (dohelp == YES)
- {
- move(HELP_ROW0, HELP_COL0);
- if (*Ip -> help)
- {
- addstr(" HELP: "); /* display "HELP:" text */
-
- move (HELP_ROW, 0); /* Erase preivous help text (if any) */
- clrtoeol();
-
- help_len = strlen(Ip -> help);
- if (help_len > (SCREEN_COLS - 6))
- move (HELP_ROW, (80 - strlen(Ip -> help))/2);
- else
- move (HELP_ROW, (80 - help_len)/2 - 2);
-
- hlight_on();
- if (help_len <= (SCREEN_COLS - 6))
- addstr(" ");
- addstr(Ip -> help);
- if (help_len <= (SCREEN_COLS - 6))
- addstr(" ");
- hlight_end();
- clrtoeol();
- }
- else
- {
- addstr(" "); /* clear help text area */
- move(HELP_ROW, 0);
- }
- clrtoeol();
- }
- }
-
-
- /************************************************************
- * get_cmd()
- * Get a command from the user.
- * Arrow keys or space returns the appropriate K_ code.
- * Pressing Enter returns the K_RUN code.
- * Pressing ! returns the K_SHELL code.
- * Entering a direct number returns K_DIRECT,
- * and the sel_val is set (indirectly) to selection number
- * (1-based).
- ************************************************************/
-
- int get_cmd(nitems, curr, sel_val)
- int nitems;
- int curr;
- int *sel_val;
- {
- int ch;
- int newval;
- int savy, savx;
-
- static int digits = FALSE; /* true if digits being entered */
-
- move(echoy, echox); /* move to prompt location */
- printw("%d", curr + 1);
- getyx(stdscr, savy, savx);
- clrtoeol();
- move(savy, savx);
- refresh();
-
- while (1)
- {
- ch = getch();
- if (!isdigit(ch))
- digits = FALSE;
- switch (ch)
- {
- case KEY_UP:
- case '\b': /* WYSE 60s send this for left arrow */
- clrtoeol();
- return KEY_UP;
-
- case ' ':
- case KEY_DOWN:
- #if UNIX || XENIX
- case '\n': /* WYSE 60s send this for down arrow */
- #endif
- clrtoeol();
- return KEY_DOWN;
-
- case KEY_RIGHT:
- case KEY_LEFT:
- case KEY_RUN:
- case KEY_SHOW:
- return ch;
-
- case 'e':
- case 'E':
- return K_EXIT;
-
- case 'x':
- case 'X':
- return K_EXITALL;
-
- case 'v':
- case 'V':
- return K_VERSION;
-
- case '!':
- return K_SHELL;
-
- case ESC: /* clear digits area */
- digits = FALSE;
- move(echoy, echox);
- clrtoeol();
- refresh();
- break;
-
- default: /* handle digits */
- if (!isdigit(ch))
- return K_UNKNOWN;
-
- if (digits &&
- (newval = *sel_val * 10 + (ch - '0')) <= nitems
- && newval > 0)
- {
- addch(ch);
- refresh();
- *sel_val = newval;
- return K_DIRECT;
- }
- else if ( (newval = ch - '0') && newval <= nitems)
- {
- digits = TRUE;
- move(echoy, echox);
- addch(ch);
- clrtoeol();
- refresh();
- *sel_val = newval;
- return K_DIRECT;
- }
- else
- {
- digits = FALSE;
- beep();
- }
- }
- }
- }
-